package g11.dao;

import g11.mis.AppointmentStatusTypeEnum;
import g11.model.Appointment;
import g11.model.Employee;
import g11.model.Patient;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class AppointmentDAOImpl implements AppointmentDAO {

	private static final Logger log = Logger
			.getLogger(AppointmentDAOImpl.class);

	private Session session;

	public Session getSession() {
		return this.session;
	}

	public AppointmentDAOImpl() {

	}

	public void cleanup() {
		if (session.isOpen())
			session.close();
		// HibernateUtil.shutdown();
	}

	public Integer createAppointment(Appointment appointment)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		Transaction tran = null;
		Integer appointmentId;
		try {
			tran = session.beginTransaction();
			appointmentId = (Integer) session.save(appointment);
			tran.commit();
		} catch (HibernateException e) {
			tran.rollback();
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentId;
	}

	public void updateAppointment(Appointment appointment) throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		Transaction tran = null;
		try {
			tran = session.beginTransaction();
			session.update(appointment);
			tran.commit();
		} catch (HibernateException e) {
			tran.rollback();
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		// TODO Auto-generated method stub

	}

	public void deleteAppointment(Appointment appointment) throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		Transaction tran = null;
		try {
			tran = session.beginTransaction();
			session.delete(appointment);
			tran.commit();
		} catch (HibernateException e) {
			tran.rollback();
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
	}

	@Override
	public List<Appointment> getAppointmentByPatient(Patient patient)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Appointment> appointmentList = new ArrayList<Appointment>();
		try {
			Query hql = session
					.createQuery("from Appointment as app where app.patient.id=?");
			hql.setInteger(0, patient.getId());
			appointmentList = hql.list();
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentList;

	}

	public List<Appointment> getPendingAppointmentByDoctor(Employee doctor)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Appointment> appointmentList = new ArrayList<Appointment>();
		try {
			Query hql = session
					.createQuery("from Appointment as app where app.status =? and app.doctor.id=?");
			hql.setInteger(0, AppointmentStatusTypeEnum.PENDING.index());
			hql.setInteger(1, doctor.getId());
			appointmentList = hql.list();
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentList;
	}

	@Override
	public List<Appointment> getPendingAppointmentByPatient(Patient patient)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Appointment> appointmentList = new ArrayList<Appointment>();
		try {
			Query hql = session
					.createQuery("from Appointment as app where app.status =? and app.patient.id=?");
			hql.setInteger(0, AppointmentStatusTypeEnum.PENDING.index());
			hql.setInteger(1, patient.getId());
			appointmentList = hql.list();
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentList;
	}

	@Override
	public Appointment getAppointmentById(Integer appointmentId)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		Appointment appointment = null;
		try {
			//
			String hql = "from Appointment as app where app.appointmentId=?";
			Query q = session.createQuery(hql);
			q.setString(0, String.valueOf(appointmentId));
			System.out.print(q.getQueryString());
			if (q.list().size() > 0) {
				appointment = (Appointment) q.list().get(0);
			}
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointment;
	}

	@Override
	public List<Appointment> getTodayAppointmentByDoctor(Employee doctor)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Appointment> appointmentList = new ArrayList<Appointment>();
		try {
			java.util.Date today = new java.util.Date();
			java.sql.Date sqlToday = new java.sql.Date(today.getTime());
			Query hql = session
					.createQuery("from Appointment as app where app.doctor.id=? and app.appointmentDate=? ");
			hql.setInteger(0, doctor.getId());
			hql.setDate(1, sqlToday);
			appointmentList = hql.list();
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentList;
	}

	@Override
	public List<Appointment> getVisitedAppointmentByTimePeriod(Date startDate,
			Date endDate) throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Appointment> appointmentList = new ArrayList<Appointment>();
		try {
			java.util.Date today = new java.util.Date();
			java.sql.Date sqlToday = new java.sql.Date(today.getTime());
			Query hql = session
					.createQuery("from Appointment as app where app.appointmentDate>=? and app.appointmentDate <=? and app.status =?");
			hql.setDate(0, startDate);
			hql.setDate(1, endDate);
			hql.setInteger(2, AppointmentStatusTypeEnum.VISITED.index());
			appointmentList = hql.list();
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentList;
	}

	@Override
	public List<Appointment> getVisitedAppointmentByDoctorAndTimePeriod(
			Date startDate, Date endDate, Employee doctor) throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Appointment> appointmentList = new ArrayList<Appointment>();
		try {
			java.util.Date today = new java.util.Date();
			java.sql.Date sqlToday = new java.sql.Date(today.getTime());
			Query hql = session
					.createQuery("from Appointment as app where app.appointmentDate>=? and app.appointmentDate <=? and app.status =? and app.doctor.id=?");
			hql.setDate(0, startDate);
			hql.setDate(1, endDate);
			hql.setInteger(2, AppointmentStatusTypeEnum.VISITED.index());
			hql.setInteger(3, doctor.getId());
			appointmentList = hql.list();
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentList;
	}

	@Override
	public List<Appointment> getVisitedAppointmentByPatientAndTimePeriod(
			Date startDate, Date endDate, Patient patient) throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Appointment> appointmentList = new ArrayList<Appointment>();
		try {
			java.util.Date today = new java.util.Date();
			java.sql.Date sqlToday = new java.sql.Date(today.getTime());
			Query hql = session
					.createQuery("from Appointment as app where app.appointmentDate>=? and app.appointmentDate <=? and app.status =? and app.patient.id=?");
			hql.setDate(0, startDate);
			hql.setDate(1, endDate);
			hql.setInteger(2, AppointmentStatusTypeEnum.VISITED.index());
			hql.setInteger(3, patient.getId());
			appointmentList = hql.list();
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentList;
	}

	@Override
	public List<Appointment> getAllVisitedAppointmentByDoctor(Employee doctor)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Appointment> appointmentList = new ArrayList<Appointment>();
		try {
			Query hql = session
					.createQuery("from Appointment as app where app.doctor.id=? and app.status =?");
			hql.setInteger(0, doctor.getId());
			hql.setInteger(1, AppointmentStatusTypeEnum.VISITED.index());
			appointmentList = hql.list();
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentList;
	}

	@Override
	public List<Appointment> getAllVisitedAppointmentByPatient(Patient patient)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Appointment> appointmentList = new ArrayList<Appointment>();
		try {
			Query hql = session
					.createQuery("from Appointment as app where app.patient.id=? and app.status =?");
			hql.setInteger(0, patient.getId());
			hql.setInteger(1, AppointmentStatusTypeEnum.VISITED.index());
			appointmentList = hql.list();
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
		return appointmentList;
	}

}
